package com.comment.aspect;

import com.comment.annotation.AccessLimit;
import com.comment.common.ResultCode;
import com.comment.common.exception.CustomException;
import com.comment.dto.CommentRequest;
import com.comment.util.RedisUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.Objects;

/**
 * @author vedeng
 * @className AccessFrequencyLimitingAspect
 * @description:
 * @date 2022/2/23 9:30
 */
@Aspect
@Component
public class AccessFrequencyLimitingAspect {

    //private final RedisUtils redisUtils = SpringUtil.getBean(RedisUtils.class);
    @Autowired
    private RedisUtils redisUtils;

    @Around(value = "@annotation(com.comment.annotation.AccessLimit)")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {


        AccessLimit accessLimit = ((MethodSignature) pjp.getSignature()).getMethod().getAnnotation(AccessLimit.class);

        //判断是否有注解
        if (Objects.isNull(accessLimit)){
            return pjp.proceed();
        }

        Object[] args = pjp.getArgs();
        Method method = ((MethodSignature) pjp.getSignature()).getMethod();
        Parameter[] parameters = method.getParameters();
        CommentRequest request = null;
        for (int i = 0; i < parameters.length; i++) {
            if (parameters[i].getType().equals(CommentRequest.class)) {
                request = (CommentRequest) args[i];
                break;
            }
        }

        if (Objects.isNull(request)){
            throw new CustomException(ResultCode.PARAM_IS_BLANK);
        }

        int seconds = accessLimit.seconds();
        int maxCount = accessLimit.maxCount();
        //boolean login = accessLimit.needLogin();

        String key = String.valueOf(request.getUserId());

        Integer count = redisUtils.get(key,Integer.class,seconds);
        if(count == null){
            //第一次访问
            redisUtils.set(key,1,seconds);
        }else if(count < maxCount){
            //加1
            redisUtils.incr(key, 1);
        }else{
            //超出访问次数
            throw new CustomException(ResultCode.COUNT_TIME_ERROR);
        }
        return pjp.proceed();
    }
}